import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;


public class PrinterTest {

	public static void main(String[] args) {
		
		System.out.println();

		listAllPrinterServices();
		
		//String[] docFlavors = {"pdf", "postscript", "gif", "pcl", "text"};
		String[] docFlavors = {"pdf", "postscript", "pcl", "gif"};
		for (String string : docFlavors) {
			listPrinterServices(string);
		}		
		
		printInputStream();
	}
	
	public static void listAllPrinterServices() {
		PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
		if (services.length > 0)
			System.out.println("Printer services available:");
		for (PrintService service : services) {
			System.out.println("- Print Service: " + service.getName());
		}
		System.out.println("-----------------------------------------------------------------\n");
	}
	
	public static void listPrinterServices(String docFlavor) {

		DocFlavor flavor;
		if (docFlavor.equalsIgnoreCase("pdf"))
			flavor = DocFlavor.INPUT_STREAM.PDF;
		else if (docFlavor.equalsIgnoreCase("postscript"))
			flavor = DocFlavor.INPUT_STREAM.POSTSCRIPT;
		else if (docFlavor.equalsIgnoreCase("GIF"))
			flavor = DocFlavor.INPUT_STREAM.GIF;
		else if (docFlavor.equalsIgnoreCase("pcl"))
			flavor = DocFlavor.INPUT_STREAM.PCL;
		else if (docFlavor.equalsIgnoreCase("text"))
			flavor = DocFlavor.INPUT_STREAM.TEXT_PLAIN_HOST;
		else
			flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
		
		PrintService[] services = PrintServiceLookup.lookupPrintServices(flavor, null);
		if (services.length == 0) {
			System.out.println("No printer has support for input stream type of " + docFlavor.toUpperCase());
		}
		else {
			System.out.println(docFlavor.toUpperCase() + " input stream supported by the following printers");
		}
		
		for (PrintService service : services) {
			System.out.println("- Print Service: " + service.getName());
		}
		System.out.println("-----------------------------------------------------------------\n");
	}
	 

	public static void printInputStream() {
		
		//String printerName = "\\\\vitech-bdc\\Dell Color_404";
		//String printerName = "\\\\vitech-bdc\\HPLJ4300_403";
		//String printerName = "\\\\vitech-bdc\\HPLJ4300_402";
		String printerName = "GS PS Printer";

		PrintService printService = getPrintService(printerName);
		
		if (printService == null && printerName != null)
			throw new RuntimeException("Specified printer " + printerName + " not found."); 

		String fileName = "c:/demo.pdf";
		//String fileName = "c:/one_page_landscape.pdf";
		//String fileName = "c:/test.txt";
		//String fileName = "c:/local-log.txt";
		
		printDocument(fileName, printService);

	}

	public static PrintService getPrintService(String printerName){
		PrintService[] printServices = findAllPrintServices();
		for (int i = 0; i < printServices.length; i++)
		{
			if (printServices[i].getName().equals(printerName))
				return printServices[i];
		}
		return null;
	}
	
	public static PrintService[] findAllPrintServices(){
		return PrintServiceLookup.lookupPrintServices(null, null);
	}

	public static void printDocument(String fileName, PrintService printService) {

		ByteArrayInputStream bais = null;
		try {
			InputStream in = new BufferedInputStream(new FileInputStream(fileName));
			byte[] bytes = new byte[in.available()];
			in.read(bytes);			
			in.close();

			DocPrintJob pj = printService.createPrintJob();
			bais = new ByteArrayInputStream(bytes);		
			Doc doc = new SimpleDoc(bais, DocFlavor.INPUT_STREAM.POSTSCRIPT, null);
			//Doc doc = new SimpleDoc(bais, DocFlavor.READER.TEXT_PLAIN, null);
			//Doc doc = new SimpleDoc(bais, DocFlavor.INPUT_STREAM.PDF, null);
			//Doc doc = new SimpleDoc(bais, DocFlavor.INPUT_STREAM.AUTOSENSE, null);
			
			pj.print(doc, null);
			
			System.out.println("Printed " + fileName + " to " + printService.getName());
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			if (bais != null) {
				try {
					bais.close();		
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
